#!/usr/bin/env python
# -*- coding: utf-8 -*-
import cexapi
import os
import platform
import re
import math
import datetime
import urllib2
import tablePrint
import sys
import time

class function:
    
    formattab = tablePrint.tableprint()
    out = sys.stdout
    
    def __init__(self):
        self.name = None
        self.logo = None
        self.members = 0
        
        
    
    #versus static Method of same Name; c.below        
    def testMethod(self,str):
        return str
    
    @staticmethod
    def testMethod(str):
        return str 

    def strRound(self,number,anzStellen):
        return str(round(number,anzStellen))
    
    def getcexapi(self,credentialFileStr,user):
        credentialFile = open(credentialFileStr, 'r+')
        for line in credentialFile:
            resultLine = re.split(';', line)  
            if resultLine[0]==user:
                apiUser=resultLine[0]
                apiCred1=resultLine[1]
                apiCred2=resultLine[2]
        return cexapi.api(apiUser, apiCred1, apiCred2)
    
    def getMusicFilePathCommand(self):
        if platform.system()=="Windows":        
            mypath="start C:\\Daten\\workspace\\PyTest\\trade\\"    
        if platform.system()=="Linux":
            mypath="cvlc /home/hannes/workspace/PythonPrjkts/CexTrade/"        
        return mypath
    
    def clearAllorders(self,cexapiInst):    
        try:
            current_orders = cexapiInst.current_orders()
            while current_orders:
                for order in current_orders:
                    print order
                    cexapiInst.cancel_order(order['id'])
                    time.sleep(1)
            current_orders = cexapiInst.current_orders()
        except:
            print "Exception with Clear Allorders"
      
    def getFromBal(self,cexapi_bal,GHSBTC,avl_orders):
        retVal=0
        try:
            retVal=float(cexapi_bal[GHSBTC][avl_orders])
        except:
            retVal=0
        return retVal 
    
    def btcForm(self,btc_val): 
        intBTC=math.trunc(btc_val)
        fracBTC=btc_val-intBTC    
        fracBTCStr=str(fracBTC)
        while len(fracBTCStr)<10:
            fracBTCStr += "0"            
        return str(intBTC)+"."+fracBTCStr[2:5]+"s"+fracBTCStr[5:10]
    
    def calcWorthCA(self,ghs_avl,btc_avl,bidAsk,btc_orders):
        worthCaL=round(ghs_avl*bidAsk,4)
        worthCaStrL=str(worthCaL)     
        sumBTCL=worthCaL+btc_avl+btc_orders        
        return {'ca':worthCaL, 'caStr':worthCaStrL, 'sumBTC':sumBTCL}
        
    
    def printStatus(self,ghs_avl,medBidAsk,btc_avl,realBidAsk,btc_orders):
        
        worthCAHsh = self.calcWorthCA(ghs_avl,medBidAsk,btc_avl,btc_orders)
        worthCaRBAHsh = self.calcWorthCA(ghs_avl,realBidAsk,btc_avl,btc_orders)
        
        now = str(datetime.datetime.now())
        
        print "\nStatus"
        print "--------------------------------------------------------------------"
        print "ghs_avl="+str(round(ghs_avl,2)),  "(worth~"+worthCAHsh['caStr']+")", "btc_avl="+self.btcForm(btc_avl),"btcOrders="+self.btcForm(btc_orders)
        print "medBidAsk="+str(round(medBidAsk,6)), "sumBTC=",round(worthCAHsh['sumBTC'],4), now[0:16]
        print "realBidAsk="+str(round(realBidAsk,6)), "sumBTC_RBA=",round(worthCaRBAHsh['sumBTC'],4), now[0:16]
        
        #chosen at just befor 3/4 on the bitcoin Clock 
        criticalBlockNo=1498  
        bitcointClock = urllib2.urlopen('http://bitcoinclock.com//')
        bitcointClockHtml = bitcointClock.read()        
        diffChange = re.search('(change:).(\d{0,7})(\D+)', bitcointClockHtml)
        blockSinceChange=float(diffChange.group(2))
        print "blockSinceChange=",blockSinceChange, "criticalBlockNo=",criticalBlockNo
        
        bitCoinDifficulty = urllib2.urlopen('http://bitcoindifficulty.com/')
        bitCoinDifficultyHtml = bitCoinDifficulty.read()        
        currDifficulty = re.search('(margin-bottom:0px;">)((\d{1,3},){1,10}(\d{1,3})).*(</h2>)',bitCoinDifficultyHtml)
        
        currDifficultyIntStr = re.sub(r",","", currDifficulty.group(2))           
        currDiffVal=float(currDifficultyIntStr)        
        
        nextDifficulty = re.search('(Next difficulty .estimate.: )((\d{1,3},){1,10}(\d{1,3}))( \D)',bitCoinDifficultyHtml)
        nextDifficultyIntStr = re.sub(r",","", nextDifficulty.group(2))
        nextDiffVal=float(nextDifficultyIntStr)        
        
        diffIncreaseFactor=nextDiffVal/currDiffVal
        print "diffIncreaseFactor=",round(diffIncreaseFactor,4)
        
        print "new Bid(from realBidAsk)@",round(realBidAsk/diffIncreaseFactor,7)
    
    def showRate(self,virtProfit, multitude,digits):
        multStr=str(multitude)
        return round(virtProfit['rate'][multStr],digits)
    
    def showRatePerc(self,virtProfit, multitude,digits):
        multStr=str(multitude)
        return round(100*(virtProfit['rate']['1']/virtProfit['rate'][multStr]-1),digits)
    
    def calcAchievableAmt(self,ghs,orderbook,bidsAsks):
        ghs2sell=ghs
        buyIndex=0
        priceIdx=0
        ghsAmt=1
        achievedAmt=0
    
        while ghs2sell>0:
            try:         
                minGHS=min(ghs2sell,orderbook[bidsAsks][buyIndex][ghsAmt])
            except:  
                print "bidsAsks=",bidsAsks
                print "buyIndex=",buyIndex
                print "ghsAmt=",ghsAmt 
                time.sleep(5) 
                raise 
            price=orderbook[bidsAsks][buyIndex][priceIdx]
            achievedAmt += price*minGHS    
            ghs2sell -= minGHS
            buyIndex +=1
        return achievedAmt
       
    def achievableRate(self,ghs,untilPower,exponent,bidsAsks,cexapi):    
        orderbook=cexapi.order_book()
        retVal={'rate':{},'archievedAmt':0}
        for sizeExp in range(0,untilPower):
            size=pow(exponent,sizeExp)
            sizeStr=str(size)
            retVal['rate'][sizeStr]=self.calcAchievableAmt(ghs*size,orderbook,bidsAsks)/(ghs*size)
        retVal['achievedAmt']=self.calcAchievableAmt(ghs,orderbook,bidsAsks)    
        retVal['achievedRate']=retVal['achievedAmt']/ghs
        return retVal
    
    def showRateProfile(self, ghs_avl, steps,exponent,bidsAsks,logging,cexapi,showTable):
        print "achievableRate"
        virtProfit=self.achievableRate(ghs_avl,steps,exponent,bidsAsks,cexapi)
        factor=1
        factorLimit=pow(exponent,steps)
    
        ghstable = [["","ghs","rate*10^4","%"]]
        while factor<factorLimit:
            print "factor=",factor
            ghstable.append(["",str(round(ghs_avl*factor,1)),str(10000*self.showRate(virtProfit, factor,7)+0.00001),str(self.showRatePerc(virtProfit, factor,4)+0.000001)]);
            factor *=exponent
        if showTable:
            self.formattab.pprint_table(self.out,ghstable)
        if logging:
            logging.info(ghstable)  
                
        return virtProfit
    
    #def estimateProfit(diskretDiffSells, diskretDiffBuys, abstand, ghsPkg):
    #    m=min(diskretDiffSells, diskretDiffBuys)
    #    return 1000*abstand*ghsPkg*(m+1)*m/2

    
    
